/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.ts.service.impl;

import com.xy.biz.ts.domain.bo.ExaminationPaperQuestionBO;
import com.xy.biz.ts.domain.bo.ExaminationQuestionBO;
import com.xy.biz.ts.domain.bo.ExaminationQuestionOptionBO;
import com.xy.biz.ts.domain.converter.ExaminationQuestionConverter;
import com.xy.biz.ts.domain.po.ExaminationQuestionPO;
import com.xy.biz.ts.domain.query.ExaminationPaperQuestionQuery;
import com.xy.biz.ts.domain.query.ExaminationQuestionQuery;
import com.xy.biz.ts.domain.resp.GetExaminationQuestionResponse;
import com.xy.biz.ts.manager.ExaminationPaperQuestionManager;
import com.xy.biz.ts.manager.ExaminationQuestionManager;
import com.xy.biz.ts.manager.ExaminationQuestionOptionManager;
import com.xy.biz.ts.service.ExaminationQuestionService;
import com.xy.lang.domain.Result;
import com.xy.tool.context.UserContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 *
 * @author wcs
 * @date 2021-3-8
 */
@Service
public class ExaminationQuestionServiceImpl implements ExaminationQuestionService {

	@Autowired
	private ExaminationQuestionManager examinationQuestionManager;

	@Autowired
	private ExaminationQuestionOptionManager examinationQuestionOptionManager;

	@Autowired
	private ExaminationPaperQuestionManager examinationPaperQuestionManager;


	@Transactional
	@Override
	public Result<?> saveExaminationQuestion(ExaminationQuestionBO examinationQuestionBO) {
		buildExaminationQuestionBO(examinationQuestionBO);
		ExaminationQuestionPO examinationQuestionPO = examinationQuestionManager.saveExaminationQuestion(examinationQuestionBO);
		if (!Objects.isNull(examinationQuestionPO)) {
			List<ExaminationQuestionOptionBO> options = examinationQuestionBO.getOptions();
            if (CollectionUtils.isEmpty(options)) {
                return Result.success();
            }
			options.forEach(op -> {
				op.setExaminationQuestionId(examinationQuestionPO.getExaminationQuestionId());
				op.setTenantId(UserContextHolder.getTenantId());
			});
			examinationQuestionOptionManager.saveAllExaminationQuestionOption(options);
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	private void buildExaminationQuestionBO(ExaminationQuestionBO examinationQuestionBO) {
		examinationQuestionBO.setCreateTime(LocalDateTime.now());
		examinationQuestionBO.setUpdateTime(LocalDateTime.now());
		examinationQuestionBO.setCreateUserId(UserContextHolder.getUserId());
		examinationQuestionBO.setTenantId(UserContextHolder.getTenantId());
		examinationQuestionBO.setDeleteFlag(false);
	}

	private void buildExaminationQuestionBOForUpdate(ExaminationQuestionBO examinationQuestionBO) {
		examinationQuestionBO.setUpdateTime(LocalDateTime.now());
	}

	@Override
	public Result<?> saveAllExaminationQuestion(Collection<ExaminationQuestionBO> collection) {
		int affectedRows = examinationQuestionManager.saveAllExaminationQuestion(collection);
		if (affectedRows > 0) {
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Transactional
	@Override
	public Result<?> updateExaminationQuestion(ExaminationQuestionBO examinationQuestionBO) {
		buildExaminationQuestionBOForUpdate(examinationQuestionBO);
		int affectedRows = examinationQuestionManager.updateExaminationQuestion(examinationQuestionBO);
		if (affectedRows > 0) {
			examinationQuestionOptionManager.deleteExaminationQuestionOptionByExaminationQuestionId(examinationQuestionBO.getExaminationQuestionId());
			List<ExaminationQuestionOptionBO> options = examinationQuestionBO.getOptions();
			options.forEach(op -> {
				op.setExaminationQuestionId(examinationQuestionBO.getExaminationQuestionId());
				op.setTenantId(UserContextHolder.getTenantId());
			});
			if (!CollectionUtils.isEmpty(options)) {
				examinationQuestionOptionManager.saveAllExaminationQuestionOption(options);
			}
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Transactional
	@Override
	public Result<?> deleteExaminationQuestion(Long examinationQuestionId) {
		int affectedRows = examinationQuestionManager.deleteExaminationQuestion(examinationQuestionId);
		if (affectedRows > 0) {
			examinationQuestionOptionManager.deleteExaminationQuestionOptionByExaminationQuestionId(examinationQuestionId);
			return Result.success();
		}
		return Result.ofErrorRowsAffected();
	}

	@Override
	public ExaminationQuestionBO getExaminationQuestion(Long examinationQuestionId) {
        ExaminationQuestionBO examinationQuestion = examinationQuestionManager.getExaminationQuestion(examinationQuestionId);
        List<ExaminationQuestionOptionBO> examinationQuestionOptionBOS = examinationQuestionOptionManager.listExaminationQuestionOption(Arrays.asList(examinationQuestion.getExaminationQuestionId()));
        examinationQuestion.setOptions(examinationQuestionOptionBOS);
        return examinationQuestion;
    }

	@Override
	public List<ExaminationQuestionBO> listExaminationQuestionById(Collection<Long> collection) {
		return examinationQuestionManager.listExaminationQuestionById(collection);
	}

	@Override
	public List<ExaminationQuestionBO> listExaminationQuestion(ExaminationQuestionQuery query) {
		List<ExaminationQuestionBO> examinationQuestionBOS = examinationQuestionManager.listExaminationQuestion(query);
		if (!CollectionUtils.isEmpty(examinationQuestionBOS)) {
			List<ExaminationQuestionOptionBO> examinationQuestionOptionBOS = examinationQuestionOptionManager.listExaminationQuestionOption(examinationQuestionBOS.stream().map(ExaminationQuestionBO::getExaminationQuestionId).collect(Collectors.toList()));
			Map<Long, List<ExaminationQuestionOptionBO>> eqoMap = examinationQuestionOptionBOS.stream().collect(Collectors.groupingBy(ExaminationQuestionOptionBO::getExaminationQuestionId));
			examinationQuestionBOS.forEach(eq ->
					eq.setOptions(
							eqoMap.get(eq.getExaminationQuestionId())
					)
			);
			return  examinationQuestionBOS;
		}
		return  examinationQuestionBOS;
	}

	@Override
	public int countExaminationQuestion(ExaminationQuestionQuery query) {
		return examinationQuestionManager.countExaminationQuestion(query);
	}

	@Override
	public Result<List<GetExaminationQuestionResponse>> pageExaminationQuestionByPaperId(Long examinationPaperId) {
		ExaminationPaperQuestionQuery query = ExaminationPaperQuestionQuery.max().examinationPaperId(examinationPaperId).build();
		List<ExaminationPaperQuestionBO> examinationPaperQuestionBOS = examinationPaperQuestionManager.listExaminationPaperQuestion(query);
		if (!CollectionUtils.isEmpty(examinationPaperQuestionBOS)) {
			Set<Long> collect = examinationPaperQuestionBOS.stream().map(e -> e.getExaminationQuestionId()).collect(Collectors.toSet());
			List<ExaminationQuestionBO> examinationQuestionBOS = examinationQuestionManager.listExaminationQuestionById(collect);
			return Result.success(ExaminationQuestionConverter.toResponse(examinationQuestionBOS));
		}
		return Result.success();
	}

}
